package com.cayte.photo.get;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;

public class CayteFileHelper {

	public CayteFileHelper() {
	}

	private static CayteFileHelper mPhotoHelper;

	public static CayteFileHelper instance() {
		if (mPhotoHelper == null) {
			mPhotoHelper = new CayteFileHelper();
		}
		return mPhotoHelper;
	}

	public boolean saveImgFile(Bitmap mImg, String nName, String mPath) {
		BufferedOutputStream bos = null;
		File mFile = new File(mPath, nName);
		try {
			bos = new BufferedOutputStream(new FileOutputStream(mFile));
			if (mImg != null) {
				return mImg.compress(Bitmap.CompressFormat.JPEG, 80, bos);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (bos != null) {
					bos.flush();
					bos.close();
				}
				mFile = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	public boolean saveImgFile(Bitmap mImg, String mPath) {
		BufferedOutputStream bos = null;
		File mFile = new File(mPath);
		if (mFile.exists())
			mFile.delete();
		try {
			bos = new BufferedOutputStream(new FileOutputStream(mFile));
			if (mImg != null) {
				return mImg.compress(Bitmap.CompressFormat.JPEG, 80, bos);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (bos != null) {
					bos.flush();
					bos.close();
				}
				mFile = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	public boolean FileChannelCopy(String inFile, String outFile) {
		try {
			File in = new File(inFile);
			File out = new File(outFile);
			if (out.exists())
				out.delete();
			FileInputStream fin = new FileInputStream(in);
			FileOutputStream fout = new FileOutputStream(out);
			FileChannel inc = fin.getChannel();
			FileChannel outc = fout.getChannel();
			int bufferLen = (int) in.length();
			ByteBuffer bb = ByteBuffer.allocateDirect(bufferLen);
			while (true) {
				int ret = inc.read(bb);
				if (ret == -1) {
					fin.close();
					fout.flush();
					fout.close();
					break;
				}
				bb.flip();
				outc.write(bb);
				bb.clear();
			}
			exifCopy(inFile, outFile);
			return true;
		} catch (Exception e) {

		}
		return false;
	}

	public boolean rename(String oldPath, String newPath) {
		try {
			File mSourceFile = new File(oldPath);
			File ff = new File(newPath);
			if (ff.exists())
				ff.delete();
			mSourceFile.renameTo(ff);
			exifCopy(oldPath, newPath);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public boolean compressImage(String oldPath, String newPath, int length) {
		try {
			Bitmap bitmap = null;
			BitmapFactory.Options opts = new BitmapFactory.Options();
			opts.inJustDecodeBounds = true;
			bitmap = BitmapFactory.decodeFile(oldPath, opts);
			opts.inJustDecodeBounds = false;
			int l = Math.max(opts.outWidth, opts.outHeight);
			int be = (int) (l / (float) length);
			if (be <= 0)
				be = 1;
			opts.inSampleSize = be;
			bitmap = BitmapFactory.decodeFile(oldPath, opts);
			saveImgFile(bitmap, newPath);
			exifCopy(oldPath, newPath);
			return true;
		} catch (OutOfMemoryError e) {
			// TODO: handle exception
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	private void exifCopy(String oldPath, String newPath) {
		// TODO Auto-generated method stub
		try {
			ExifInterface oldExif = new ExifInterface(oldPath);
			ExifInterface newExif = new ExifInterface(newPath);
			// System.out.println("file exif -->" + oldPath + "\n"
			// + FileHelper.getInstance().printExif(oldPath));
			if (oldExif.getAttribute(ExifInterface.TAG_ORIENTATION) != null)
				newExif.setAttribute(ExifInterface.TAG_ORIENTATION,
						oldExif.getAttribute(ExifInterface.TAG_ORIENTATION));
			if (oldExif.getAttribute(ExifInterface.TAG_DATETIME) != null)
				newExif.setAttribute(ExifInterface.TAG_DATETIME,
						oldExif.getAttribute(ExifInterface.TAG_DATETIME));
			if (oldExif.getAttribute(ExifInterface.TAG_FLASH) != null)
				newExif.setAttribute(ExifInterface.TAG_FLASH,
						oldExif.getAttribute(ExifInterface.TAG_FLASH));
			if (oldExif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) != null)
				newExif.setAttribute(ExifInterface.TAG_GPS_LATITUDE,
						oldExif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
			if (oldExif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF) != null)
				newExif.setAttribute(
						ExifInterface.TAG_GPS_LATITUDE_REF,
						oldExif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF));
			if (oldExif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE) != null)
				newExif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE,
						oldExif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
			if (oldExif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF) != null)
				newExif.setAttribute(
						ExifInterface.TAG_GPS_LONGITUDE_REF,
						oldExif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF));
			if (oldExif.getAttribute(ExifInterface.TAG_MAKE) != null)
				newExif.setAttribute(ExifInterface.TAG_MAKE,
						oldExif.getAttribute(ExifInterface.TAG_MAKE));
			if (oldExif.getAttribute(ExifInterface.TAG_MODEL) != null)
				newExif.setAttribute(ExifInterface.TAG_MODEL,
						oldExif.getAttribute(ExifInterface.TAG_MODEL));
			if (oldExif.getAttribute(ExifInterface.TAG_WHITE_BALANCE) != null)
				newExif.setAttribute(ExifInterface.TAG_WHITE_BALANCE,
						oldExif.getAttribute(ExifInterface.TAG_WHITE_BALANCE));
			newExif.saveAttributes();
			// System.out.println("file exif -->" + newPath + "\n"
			// + FileHelper.getInstance().printExif(newPath));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public String printExif(String path) {
		// TODO Auto-generated method stub
		StringBuffer sb = new StringBuffer();
		try {
			ExifInterface exif = new ExifInterface(path);
			sb.append("<");
			sb.append(exif.getAttribute(ExifInterface.TAG_ORIENTATION) + "><");
			sb.append(exif.getAttribute(ExifInterface.TAG_DATETIME) + "><");
			sb.append(exif.getAttribute(ExifInterface.TAG_FLASH) + "><");
			sb.append(exif.getAttribute(ExifInterface.TAG_MAKE) + "><");
			sb.append(exif.getAttribute(ExifInterface.TAG_MODEL) + "><");
			sb.append(exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE) + "><");
			sb.append(">");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return sb.toString();
	}

	public Bitmap loadImageFromFile(String path) {
		Bitmap bitmap = null;
		try {
			bitmap = BitmapFactory
					.decodeFile(path, new BitmapFactory.Options());
		} catch (Exception e) {
			// TODO: handle exception
		}
		return bitmap;
	}

	public Bitmap loadImageFromFile(String path, int width) {
		Bitmap bitmap = null;
		FileInputStream fs = null;
		BufferedInputStream bs = null;
		try {
			fs = new FileInputStream(path);
			bs = new BufferedInputStream(fs);
			BitmapFactory.Options opts = new BitmapFactory.Options();
			opts.inJustDecodeBounds = true;
			bitmap = BitmapFactory.decodeFile(path, opts);
			opts.inJustDecodeBounds = false;
			int be = (int) (opts.outWidth / (float) width);
			if (be <= 0)
				be = 1;
			opts.inSampleSize = be;
			bitmap = BitmapFactory.decodeStream(bs, null, opts);
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			try {
				bs.close();
				fs.close();
			} catch (Exception e) {
			}
		}
		return bitmap;
	}
}
